[设计模式]之十六:观察者模式


定义

观察者模式又叫发布订阅模式(public/subscribe),定义一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

UML

示例代码

//抽象出Notifier接口,保持所有被观察者对象的引用,并管理通知 notify
abstract class INotifier {
    private List observers = new ArrayList<>();

    public void attach(IObserver observer) {
        observers.add(observer);
    }

    public void detach(IObserver observer) {
        observers.remove(observer);
    }

    public void notifyObserver() {
        for (int i = 0; i < observers.size(); i++) {
            observers.get(i).update();
        }
    }
}
// 具体的通知者 管理控制具体的观察者对象  管理自己需要变化的状态
public class ConcreteNotifier extends INotifier {
    private String state;

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

}
//抽象观察者。观察者需要在得到通知后更新自己 所以需要更新方法
abstract class IObserver {
    // 更新接口
    public abstract void update();
}
//具体观察者 它会有一个状态  在update的时候从对应的notifier获取新状态
public class ConcreteObserver extends IObserver {

    private String name;
    private String observerState;
    private ConcreteNotifier notifier;

    public ConcreteObserver(ConcreteNotifier notifier, String name) {
        // TODO Auto-generated constructor stub
        this.notifier = notifier;
        this.name = name;
    }

    @Override
    public void update() {
        // TODO Auto-generated method stub
        observerState = notifier.getState();
        System.out.println("Observer " + name + "'s new state is " + observerState);
    }

}

//客户代码
public void start() {
    //创建通知者
    ConcreteNotifier notifier = new ConcreteNotifier();
    //添加观察者
    notifier.attach(new ConcreteObserver(notifier, "X"));
    notifier.attach(new ConcreteObserver(notifier, "Y"));
    //通知更新状态
    notifier.setState("hahaha");
    //告诉观察者开始改状态
    notifier.notifyObserver();
}
//输出
Observer X's new state is hahaha
Observer Y's new state is hahaha

评价

一个对象改变需要同时改变其他对象的时候,且它不知道具体有多少对象有待改变时,考虑使用观察者模式。

观察者模式做的工作其实就是在解耦合,让耦合双方都依赖抽象,而不是依赖具体。从而使得各自变化都不会影响另一边变化。

但上面代码还有一个小问题,就是INotifier依赖IObserver。如果通知者和观察者互相不知道对方,由客户端来决定,那么就会更灵活。所以还需要一层解耦。

https://www.kancloud.cn/digest/suski-pattern/160469


文章作者: Wossoneri
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC 4.0 许可协议。转载请注明来源 Wossoneri !
评论
  目录